package service

import (
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
	"github.com/google/uuid"
	"github.com/zhang201702/zhang/zlog"
	"usad2/app/dao"
)

type PptService struct {
	BaseService
	PptPageService Service
}

func init() {
	registerService("ppt", func(name string) Service {
		return &PptService{
			BaseService:    newBaseService(name),
			PptPageService: NewService("ppt_page"),
		}
	})
}

func (service *PptService) handleFetch(item g.Map) {
	item["masters"] = service.toList(item["masters"])
	item["pages"] = service.toList(item["pages"])
	item["resources"] = service.toList(item["resources"])
	item["default"] = service.toMap(item["default"])
}

func (service *PptService) handleSave(data g.Map) {
	data["masters"] = service.toListString(data["masters"])
	data["pages"] = service.toListString(data["pages"])
	data["resources"] = service.toListString(data["resources"])
	data["default"] = service.toMapString(data["default"])
}

func (service *PptService) Fetch(id string) (result g.Map, err error) {
	result, err = service.Dao.Fetch(id)
	if err != nil {
		return result, err
	}
	service.handleFetch(result)

	pages := result["pages"].(g.List)
	masters := result["masters"].(g.List)
	fetchPages := func(list *g.List) {
		for i := range *list {
			listPage := (*list)[i]
			pageId := gconv.String(listPage["id"])
			page, err2 := service.PptPageService.Fetch(pageId)
			if err2 != nil {
				zlog.Error(err2, "获取ppt页内容时异常")
				continue
			}
			listPage["items"] = page["items"]
		}
	}
	fetchPages(&pages)
	fetchPages(&masters)

	return result, err
}

func (service *PptService) List(data g.Map) (list g.List, err error) {
	list, err = service.Dao.List(data)
	if err != nil {
		return list, err
	}
	for i := range list {
		item := list[i]
		service.handleFetch(item)
	}
	return list, err
}

func (service *PptService) Save(data g.Map) (result interface{}, err error) {

	if cpId, ok := data["copy_page_id"]; ok {
		delete(data, "copy_page_id")
		pages := data["pages"].([]interface{})
		for i := range pages {
			page := pages[i].(map[string]interface{})
			if page["id"] == cpId {
				newPage := service.copyPptPage(page)
				pages = append(pages, newPage)
				data["pages"] = pages
			}
		}
	} else if dpId, ok := data["delete_page_id"]; ok {
		delete(data, "delete_page_id")
		pages := data["pages"].([]interface{})
		for i := range pages {
			page := pages[i].(map[string]interface{})
			if page["id"] == dpId {
				pages = append(pages[:i], pages[i+1:]...)
				data["pages"] = pages
				service.PptPageService.Delete(gconv.String(dpId))
				break
			}
		}
	}
	id := gconv.String(data["id"])
	service.handleSave(data)
	if id != "" {
		result0, _ := service.Dao.Fetch(id)
		if result0 == nil {
			result, err = service.Dao.Insert(data)
		} else {
			result, err = service.Dao.Save(data)
		}
	} else {
		result, err = service.Dao.Save(data)
	}

	ppt, err := service.Dao.Fetch(gconv.String(data["id"]))
	service.handleFetch(ppt)

	return ppt, err
}

func (service *PptService) copyPptPage(page g.Map) g.Map {
	id := gconv.String(page["id"])

	curPage, _ := service.PptPageService.Fetch(id)
	items := curPage["items"].([]map[string]interface{})

	newPage := service.copyData(page)
	newPage["id"] = uuid.New().String()
	newPage["items"] = curPage["items"]
	newPage["name"] = gconv.String(page["name"]) + " copy"
	for i := range items {
		items[i]["id"] = uuid.New().String()
	}

	service.PptPageService.Save(newPage)
	delete(newPage, "items")
	return newPage
}

func (service *PptService) Delete(id string) (result interface{}, err error) {
	result, err = service.Dao.Delete(id)
	if err == nil {
		textDao := dao.BaseDao{Name: "ppt_text"}
		_, err = textDao.DeleteAll(g.Map{"pptId": id})
		if err != nil {
			zlog.Error(err, "删除ppt text 异常")
		}
	}
	return result, err
}

func (service *PptService) Copy(id string) (result interface{}, err error) {
	source, err := service.Fetch(id)
	result = source
	pptId := uuid.New().String()
	source["id"] = pptId
	source["name"] = gconv.String(source["name"]) + " copy"
	pages := source["pages"].(g.List)
	masters := source["masters"].(g.List)
	genNewPage := func(list *g.List) {
		for i := range *list {
			page := (*list)[i]
			page["id"] = uuid.New().String()
			page["pptId"] = pptId
			items := page["items"].(g.List)

			for k := range items {
				items[k]["id"] = uuid.New().String()
			}

			service.PptPageService.Save(page)
			delete(page, "items")
		}
	}
	genNewPage(&pages)
	genNewPage(&masters)

	result, err = service.Save(source)
	if err != nil {
		zlog.Error(err, "copy 保存时，异常")
		result = nil
	}
	return result, nil
}
